// 拆分计算阶段和格式化阶段
function createStatement(invoice, plays) {
  let statementData = {};
  statementData.invoice = cloneData(invoice);
  statementData.amountFor = amountFor;
  statementData.totalAmount = totalAmount;
  statementData.volumeCreditsFor = volumeCreditsFor;
  statementData.totalVolumeCredits = totalVolumeCredits;
  statementData.usd = usd;
  initPlay(statementData, plays);
  return statementData;
}


// 将play对象挂载到performance对象上
function initPlay(statementData, plays) {
  for (let performance of statementData.invoice.performances) {
    performance.play = cloneData(plays[performance.playID]);
  }
}

// 对象克隆
function cloneData(data) {
  return Object.assign({}, data);
}

// 提炼函数，计算戏剧对应金额
function amountFor(performance) {
  let result = 0;
  switch (performance.play.type) {
    case "tragedy":
      result = 40000;
      if (performance.audience > 30) {
        result += 1000 * (performance.audience - 30);
      }
      break;
    case "comedy":
      result = 30000;
      if (performance.audience > 20) {
        result += 10000 + 500 * (performance.audience - 20);
      }
      break;
    default:
      throw new Error(`unknown type: ${performance.play.type}`);
  }
  return result;
}

// 代码搬移，计算总金额
function totalAmount(invoice) {
  return invoice.performances.reduce((prev, curr) => prev + amountFor(curr), 0);
}

// 提炼函数，计算戏剧对应积分
function volumeCreditsFor(performance) {
  let result = 0;
  // 增加积分
  // add volume credits
  result += Math.max(performance.audience - 30, 0);
  // 为什么是除以5呢？ 如果是除以10的话，大于5小于10的结果就是0
  // 如果是喜剧类型的戏剧，每多10个听众就增加1积分
  // add extra credit for every ten comedy attendees
  if ("comedy" === performance.play.type) {
    result += Math.floor(performance.audience / 5);
  }
  return result;
}

// 代码搬移，计算总积分
function totalVolumeCredits(invoice) {
  return invoice.performances.reduce((prev, curr) => prev + volumeCreditsFor(curr), 0);
}

// 内联变量，格式化金额
function usd(amount) {
  return new Intl.NumberFormat("en-US",
    {style: "currency", currency: "USD", minimumFractionDigits: 2}).format(amount / 100);
}

export { createStatement };